package com.cjx.learn.service;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cjx.learn.config.MqConfig;
import com.cjx.learn.dto.MessageInfo;
import com.cjx.learn.utils.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.EOFException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * websocket
 * @author cjunxian
 * @date 2021/9/3
 */
@Slf4j
@Component
@ServerEndpoint("/webmq/{username}")
public class WebsocketHandler {

    private static final String WEBMQ_PREFIX = "webmq:user:";

    Session session;

    String username;

    private static String getQueueName(){
        MqConfig config = (MqConfig) SpringUtils.getBean(MqConfig.BEAN_NAME);
        return config.getQueueName();
    }

    private static IRedisService getRedisService(){
       return  (IRedisService) SpringUtils.getBean(IRedisService.SERVICE_BEAN_NAME);
    }

    private static RabbitTemplate getRabbitTemplate(){
        return SpringUtils.getBean(RabbitTemplate.class);
    }


    /**
     * 保存websocket连接
     */
    private final static Map<String,WebsocketHandler> clients = new ConcurrentHashMap<>();

    @OnOpen
    public void onOpen(@PathParam("username")String username,Session session){
        log.info("有客户端连接进来了！");
        this.session = session;
        this.username = username;
        clients.remove(username);
        clients.put(username,this);
        //注册队列到redis
        WebsocketHandler.getRedisService().set(WEBMQ_PREFIX + username,WebsocketHandler.getQueueName());
    }

    @OnClose
    public void onClose(){
        clients.remove(username);
        WebsocketHandler.getRedisService().del(WEBMQ_PREFIX + this.username);
    }


    @OnError
    public void onError(Throwable error) {
        log.error("用户错误:" + this.username + ",原因:" + error.getMessage());
        if(error instanceof EOFException){
            log.error("用户"+this.username+"断开连接！");
            this.onClose();
        }
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message) {
        log.info("app端发来的信息是:" + message);
        //将消息写入队列
        MessageInfo messageInfo = JSONObject.parseObject(message, MessageInfo.class);
        //从redis中查询该用户的队列
        String queue = (String) getRedisService().get(WEBMQ_PREFIX + messageInfo.getUsername());
        getRabbitTemplate().convertAndSend(queue,messageInfo);
    }

    /**
     * 向执行某个任务的客户端发送消息
     */
    public static void sendMessage(String username,String message) {
        if(CollUtil.isNotEmpty(clients)){
            WebsocketHandler websocketHandler = clients.get(username);
            if(websocketHandler!=null){
                websocketHandler.session.getAsyncRemote().sendText(message);
            }
        }
    }

}
